package com.kmia.bjs.flightserver.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kmia.bjs.flightserver.config.BaseConfig;
import com.kmia.bjs.flightserver.config.FlightStateEnum;
import com.kmia.bjs.flightserver.dao.DepartureMapper;
import com.kmia.bjs.flightserver.entity.Departure;
import com.kmia.bjs.flightserver.entity.Location;
import com.kmia.bjs.flightserver.service.IDepartureService;
import com.kmia.bjs.flightserver.util.DateUtil;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.util.List;

/**
 * @Description TODO
 * @Author 4K
 * @Date 2022/4/29 16:42
 * @Version 1.0
 **/
@Service
public class DepartureServiceImpl extends ServiceImpl<DepartureMapper, Departure> implements IDepartureService<Departure> {

    @Autowired
    private LocationServiceImpl locationService;

    /**
     * @param fDate State
     * @return List<Departure> 返回按ID倒排
     * @Description 根据航班日期查询
     * @Version1.0
     * @author 4K
     * @date 2022/5/10 9:39
     **/
    public List<Departure> findByFDate(String fDate, String State) {
        QueryWrapper<Departure> wrapper = new QueryWrapper<>();
        wrapper.eq("SDT", fDate);
        if (State != null && !"".equals(State)) {
            wrapper.eq("STATE", State);
        }
        wrapper.orderByDesc("id");
        return super.list(wrapper);
    }

    /**
     * @param fDate flt flightRepeat
     * @return Departure
     * @Description 根据航班日期、航班号、重复号查询航班
     * @Version1.0
     * @author 4K
     * @date 2022/5/10 9:42
     **/
    public Departure findByFDateFltFlightRepeat(String fDate, String flt, String flightRepeat) {
        QueryWrapper<Departure> wrapper = new QueryWrapper<>();
        wrapper.eq("SDT", fDate);
        wrapper.eq("FLT", flt);
        wrapper.eq("FLIGHTREPEAT", flightRepeat);
        return super.getOne(wrapper);
    }

    /**
     * @param
     * @return
     * @Description 新增/修改
     * @Version1.0
     * @author 4K
     * @date 2022/5/10 16:36
     **/
    public Departure editFromXML(String flightXML) {
        // 读取xml
        SAXReader saxReader = new SAXReader();
        Document document;
        Element headerElement;
        Element bodyElement = null;
        List<Element> headElements;
        List<Element> bodyElements;
        String requestType = null;

        // 航班号
        String FLT = "";
        // 航班日期
        String SDT = "";
        // 三字码
        String IFC = "";
        // 二字码
        String FLC = "";
        // 计划离港时间
        String STD = "";
        // 计划到港时间
        String STA = "";
        // 预计起飞时间
        String ETD = "";
        // 预计到达时间
        String ETA = "";
        // 实际撤轮挡时间
        String ATD = "";
        // 实际上轮档时间
        String ATA = "";
        // 起飞时间
        String ABT = "";
        // 触地时间
        String TDT = "";
        // 出港机位\到达机位
        String TAR = "";
        // 机型
        String ITY = "";
        // 飞机编号
        String REG = "";
        // 航班性质（大类）
        String NAT = "";
        // 航班性质（大类细分）
        String FST = "";
        // 航班分类
        String CLA = "";
        // 航段操作类型
        String OTC = "";
        // 始发站
        String ORG = "";
        // 终点站
        String DES = "";
        // 登机门开启时间
        String GOT = "";
        //状态标识：起飞、到达、取消、备降、返航等
        String FLIGHTSTAUS = "";
        // 重复号
        String FLIGHTREPEAT = "";

        try {
            document = saxReader.read(new ByteArrayInputStream(flightXML.getBytes("UTF-8")));
            // 获取根元素
            Element root = document.getRootElement();
            // 获取Header子元素
            headerElement = root.element("Header");

            // 创建xml文件:使用了一个Helper类
            Document saveDocument = DocumentHelper.createDocument();
            saveDocument.setXMLEncoding("UTF-8");
            // 创建根节点并添加进文档
            Element saveRoot = saveDocument.addElement("Envelope", "http://schema.kmia.com");
            Element header = saveRoot.addElement("Header");

            if (headerElement != null) {
                headElements = headerElement.elements();
                for (int i = 0; i < headElements.size(); i++) {
                    header.addElement(headElements.get(i).getName()).setText(headElements.get(i).getText());
                    // xml消息类型
                    if ("RequestType".equals(headElements.get(i).getName())) {
                        requestType = headElements.get(i).getText();
                    }
                }
            }
            // 获取Body子元素
            bodyElement = root.element("Body");
            if (bodyElement != null) {
                bodyElements = bodyElement.elements();
                // 创建Body子元素
                Element body = saveRoot.addElement("Body");
                List<Element> flightElement;
                Element flight;
                for (Element e : bodyElements) {
                    flightElement = e.elements();
                    flight = body.addElement("Flight");
                    for (int i = 0; i < flightElement.size(); i++) {
                        flight.addElement(flightElement.get(i).getName()).setText(flightElement.get(i).getText());
                        if ("FlightNo".equals(flightElement.get(i).getName())) {
                            FLT = flightElement.get(i).getText();
                        }
                        if ("FlightDate".equals(flightElement.get(i).getName())) {
                            SDT = flightElement.get(i).getText();
                        }
                        if ("FlightRepeat".equals(flightElement.get(i).getName())) {
                            FLIGHTREPEAT = flightElement.get(i).getText();
                        }
                        if ("IFC".equals(flightElement.get(i).getName())) {
                            IFC = flightElement.get(i).getText();
                        }
                        if ("FLC".equals(flightElement.get(i).getName())) {
                            FLC = flightElement.get(i).getText();
                        }
                        if ("Std".equals(flightElement.get(i).getName())) {
                            STD = flightElement.get(i).getText();
                        }
                        if ("Sta".equals(flightElement.get(i).getName())) {
                            STA = flightElement.get(i).getText();
                        }
                        if ("Etd".equals(flightElement.get(i).getName())) {
                            ETD = flightElement.get(i).getText();
                        }
                        if ("Eta".equals(flightElement.get(i).getName())) {
                            ETA = flightElement.get(i).getText();
                        }
                        if ("Atd".equals(flightElement.get(i).getName())) {
                            ATD = flightElement.get(i).getText();
                        }
                        if ("Ata".equals(flightElement.get(i).getName())) {
                            ATA = flightElement.get(i).getText();
                        }
                        if ("Abt".equals(flightElement.get(i).getName())) {
                            ABT = flightElement.get(i).getText();
                        }
                        if ("Tdt".equals(flightElement.get(i).getName())) {
                            TDT = flightElement.get(i).getText();
                        }
                        if ("Stand".equals(flightElement.get(i).getName())) {
                            TAR = flightElement.get(i).getText();
                        }
                        if ("ITY".equals(flightElement.get(i).getName())) {
                            ITY = flightElement.get(i).getText();
                        }
                        if ("Airnum".equals(flightElement.get(i).getName())) {
                            REG = flightElement.get(i).getText();
                        }
                        if ("Nat".equals(flightElement.get(i).getName())) {
                            NAT = flightElement.get(i).getText();
                        }
                        if ("Fst".equals(flightElement.get(i).getName())) {
                            FST = flightElement.get(i).getText();
                        }
                        if ("Cla".equals(flightElement.get(i).getName())) {
                            CLA = flightElement.get(i).getText();
                        }
                        if ("Otc".equals(flightElement.get(i).getName())) {
                            OTC = flightElement.get(i).getText();
                        }
                        if ("Org".equals(flightElement.get(i).getName())) {
                            ORG = flightElement.get(i).getText();
                        }
                        if ("Des".equals(flightElement.get(i).getName())) {
                            DES = flightElement.get(i).getText();
                        }
                        if ("GOT".equals(flightElement.get(i).getName())) {
                            GOT = flightElement.get(i).getText();
                        }
                        if ("FlightStaus".equals(flightElement.get(i).getName())) {
                            FLIGHTSTAUS = flightElement.get(i).getText();
                        }
                    }
                }
            }

        } catch (Exception e) {
            log.error("读取消息出错：" + e);
        }

        Departure departure;
        Location location;
        String state;

        departure = findByFDateFltFlightRepeat(SDT, FLT, FLIGHTREPEAT);
        if (departure != null) { // 修改
            try {
                departure.setIFC(IFC);
                departure.setFLC(FLC);
                departure.setSTD(DateUtil.parse(STD, "yyyy-MM-dd HH:mm:ss"));
                departure.setETD(DateUtil.parse(ETD, "yyyy-MM-dd HH:mm:ss"));
                departure.setATD(DateUtil.parse(ATD, "yyyy-MM-dd HH:mm:ss"));
                departure.setABT(DateUtil.parse(ABT, "yyyy-MM-dd HH:mm:ss"));
                departure.setTAR(TAR);
                departure.setITY(ITY);
                departure.setREG(REG);
                departure.setNAT(NAT);
                departure.setFST(FST);
                departure.setCLA(CLA);
                departure.setOTC(OTC);
                departure.setORG(ORG);
                location = locationService.findByIataCode(ORG);
                if (location == null) {
                    departure.setORGCHN(ORG);// 始发站(中文);
                } else {
                    departure.setORGCHN(location.getNamechn());// 始发站(中文);
                }
                departure.setDES(DES);
                location = locationService.findByIataCode(DES);
                if (location == null) {
                    departure.setDESCHN(DES);// 目的站(中文);
                } else {
                    departure.setDESCHN(location.getNamechn());// 目的站(中文);
                }
                if (location == null) {
                    departure.setTOF("");//航段性质
                } else {
                    departure.setTOF(location.getFlightSector());
                }
                departure.setGOT(DateUtil.parse(GOT, "yyyy-MM-dd HH:mm:ss"));
                departure.setFLIGHTSTAUSCODE(FLIGHTSTAUS);
                departure.setFLIGHTSTAUS(FlightStateEnum.valueOf(FLIGHTSTAUS).getDes());
                //  如果原来的航班状态为删除，则为删除后新增的相同航班号，航班日期，重复号的航班，设置状态为正常
                state = departure.getSTATE(); // 原航班状态
                if ("DE".equals(state)) {
                    departure.setSTATE("NO");
                }
                // 自动对状态为“AB”（已起飞）的出港航班进行归档
                if ("AB".equals(FLIGHTSTAUS)) {
                    // todo 更新旅客人数
                    departure.setSTATE("RF"); // 登机确认
                }
                update(departure, null);
            } catch (Exception e) {
                log.error("修改出港航班出错：", e);
            }
        } else {

            try {
                departure = new Departure();
                departure.setFLT(FLT);
                departure.setNFLT(setNFLT(SDT)); // 设置公务机系统生成并传到安检系统的航班号
                departure.setSDT(DateUtil.parse(SDT, "yyyy-MM-dd"));
                departure.setFLIGHTREPEAT(FLIGHTREPEAT);
                departure.setIFC(IFC);
                departure.setFLC(FLC);
                departure.setSTD(DateUtil.parse(STD, "yyyy-MM-dd HH:mm:ss"));
                departure.setETD(DateUtil.parse(ETD, "yyyy-MM-dd HH:mm:ss"));
                departure.setATD(DateUtil.parse(ATD, "yyyy-MM-dd HH:mm:ss"));
                departure.setABT(DateUtil.parse(ABT, "yyyy-MM-dd HH:mm:ss"));
                departure.setTAR(TAR);
                departure.setITY(ITY);
                departure.setREG(REG);
                departure.setNAT(NAT);
                departure.setFST(FST);
                departure.setCLA(CLA);
                departure.setOTC(OTC);
                departure.setORG(ORG);
                location = locationService.findByIataCode(ORG);
                if (location == null) {
                    departure.setORGCHN(ORG);// 始发站(中文);
                } else {
                    departure.setORGCHN(location.getNamechn());// 始发站(中文);
                }
                departure.setDES(DES);
                location = locationService.findByIataCode(DES);
                if (location == null) {
                    departure.setDESCHN(DES);// 目的站(中文);
                } else {
                    departure.setDESCHN(location.getNamechn());// 目的站(中文);
                }
                if (location == null) {
                    departure.setTOF("");//航段性质
                } else {
                    departure.setTOF(location.getFlightSector());
                }
                departure.setGOT(DateUtil.parse(GOT, "yyyy-MM-dd HH:mm:ss"));
                departure.setSTATE("NO");
                departure.setFLIGHTSTAUSCODE(FLIGHTSTAUS);
                departure.setFLIGHTSTAUS(FlightStateEnum.valueOf(FLIGHTSTAUS).getDes());
                save(departure);
            } catch (Exception e) {
                departure = null;
                log.error("新增出港航班出错：" + e);
            }
        }

        return departure;
    }


    /**
     * @param
     * @return
     * @Description 查询计划日期当天是否已经有公务机，有则取最后一个公务机安检航班号+1，没有则从1001开始
     * @author 4K
     * @date 2022/5/10 16:32
     **/
    private String setNFLT(String SDT) {
        StringBuffer nFLT = new StringBuffer("XX");
        // 查询计划日期当天是否已经有公务机，有则取最后一个公务机安检航班号+1，没有则从1001开始
        List<Departure> departures = this.findByFDate(SDT, null);
        if (departures != null && !departures.isEmpty()) {
            String lastNFLT = departures.get(0).getNFLT();
            String nextNFLT = lastNFLT.substring(2);
            int nextNFLTNumber = Integer.valueOf(nextNFLT);
            nextNFLTNumber = nextNFLTNumber + 1;
            nFLT.append(nextNFLTNumber);
        } else {
            nFLT.append(BaseConfig.NFLT_Number);
        }
        return nFLT.toString();
    }
}
